package com.autoglm.android.core.db

import androidx.room.Dao
import androidx.room.Database
import androidx.room.Delete
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.RoomDatabase
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import androidx.room.Update
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

/**
 * 应用实体
 */
@Entity(tableName = "apps")
data class AppEntity(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val name: String,
    val packageName: String
)

/**
 * 屏幕实体
 */
@Entity(tableName = "screens")
data class ScreenEntity(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val appId: Int,
    val name: String,
    val description: String,
    val activityName: String
)

/**
 * UI元素实体
 */
@Entity(tableName = "elements")
data class ElementEntity(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val screenId: Int,
    val elementId: String,
    val description: String,
    val resourceId: String?,
    val className: String?,
    val text: String?,
    val contentDescription: String?,
    val bounds: String?
)

/**
 * 操作实体
 */
@Entity(tableName = "operations")
data class OperationEntity(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val appId: Int,
    val name: String,
    val description: String,
    val steps: String
)

/**
 * 类型转换器
 */
class Converters {
    @TypeConverter
    fun fromString(value: String): List<String> {
        val listType = object : TypeToken<List<String>>() {}.type
        return Gson().fromJson(value, listType)
    }
    
    @TypeConverter
    fun fromList(list: List<String>): String {
        return Gson().toJson(list)
    }
}

/**
 * 应用DAO
 */
@Dao
interface AppDao {
    @Query("SELECT * FROM apps WHERE name = :name")
    suspend fun getAppByName(name: String): AppEntity?
    
    @Query("SELECT * FROM apps WHERE packageName = :packageName")
    suspend fun getAppByPackage(packageName: String): AppEntity?
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(app: AppEntity): Long
    
    @Update
    suspend fun update(app: AppEntity)
    
    @Delete
    suspend fun delete(app: AppEntity)
    
    @Query("SELECT * FROM apps")
    suspend fun getAllApps(): List<AppEntity>
}

/**
 * 屏幕DAO
 */
@Dao
interface ScreenDao {
    @Query("SELECT * FROM screens WHERE appId = :appId")
    suspend fun getScreensByAppId(appId: Int): List<ScreenEntity>
    
    @Query("SELECT * FROM screens WHERE appId = :appId AND name = :name")
    suspend fun getScreenByNameAndAppId(name: String, appId: Int): ScreenEntity?
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(screen: ScreenEntity): Long
    
    @Update
    suspend fun update(screen: ScreenEntity)
    
    @Delete
    suspend fun delete(screen: ScreenEntity)
}

/**
 * 元素DAO
 */
@Dao
interface ElementDao {
    @Query("SELECT * FROM elements WHERE screenId = :screenId")
    suspend fun getElementsByScreenId(screenId: Int): List<ElementEntity>
    
    @Query("SELECT * FROM elements WHERE screenId = :screenId AND elementId = :elementId")
    suspend fun getElementByIdAndScreenId(elementId: String, screenId: Int): ElementEntity?
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(element: ElementEntity): Long
    
    @Update
    suspend fun update(element: ElementEntity)
    
    @Delete
    suspend fun delete(element: ElementEntity)
}

/**
 * 操作DAO
 */
@Dao
interface OperationDao {
    @Query("SELECT * FROM operations WHERE appId = :appId")
    suspend fun getOperationsByAppId(appId: Int): List<OperationEntity>
    
    @Query("SELECT * FROM operations WHERE appId = :appId AND name = :name")
    suspend fun getOperationByNameAndAppId(name: String, appId: Int): OperationEntity?
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(operation: OperationEntity): Long
    
    @Update
    suspend fun update(operation: OperationEntity)
    
    @Delete
    suspend fun delete(operation: OperationEntity)
}

/**
 * 应用知识数据库
 */
@Database(
    entities = [
        AppEntity::class,
        ScreenEntity::class,
        ElementEntity::class,
        OperationEntity::class
    ],
    version = 1,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class AppKnowledgeDatabase : RoomDatabase() {
    abstract fun appDao(): AppDao
    abstract fun screenDao(): ScreenDao
    abstract fun elementDao(): ElementDao
    abstract fun operationDao(): OperationDao
} 